﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using PostSharp.Aspects;

namespace LiveWebServiceBase.AOPLogWriter
{
    [Serializable]
    public sealed class LogWriterAspect : OnMethodBoundaryAspect
    {
        private DateTime dtStartTime;
        private MethodFormatStrings methodFormatStrings;

        public override void CompileTimeInitialize(System.Reflection.MethodBase method, AspectInfo aspectInfo)
        {
            this.methodFormatStrings = Formatter.GetMethodFormatStrings(method);

        }
        public override void OnEntry(MethodExecutionArgs args)
        {
            dtStartTime = DateTime.Now;
        }

        public override void OnExit(MethodExecutionArgs args)
        {
            TimeSpan tsExecutionTime = DateTime.Now - dtStartTime;

            if (tsExecutionTime > TimeSpan.FromSeconds(5))
                ProceedData(args, EventLogEntryType.Warning, tsExecutionTime);
            else if (Settings.Logging.IsEnableLogging)
                ProceedData(args, EventLogEntryType.Information, tsExecutionTime);
        }

        public override void OnException(MethodExecutionArgs args)
        {
            ProceedData(args, EventLogEntryType.Error, TimeSpan.Zero);
        }

        private void ProceedData(MethodExecutionArgs args, EventLogEntryType eletItem, TimeSpan tsExecutionTime)
        {
            Settings.Logging.LogItem liItem = new Settings.Logging.LogItem();

            liItem.ExecutionTime = tsExecutionTime;
            liItem.ServiceUserName = System.Web.HttpContext.Current.User.Identity.Name;
            liItem.ClientIP = System.Web.HttpContext.Current.Request.UserHostAddress;

            liItem.LiveID = "None";
            liItem.Arguments = new List<string>();

            int index = 0;
            object[] masArg = args.Arguments.ToArray();
            foreach (ParameterInfo item in args.Method.GetParameters())
            {
                string argumentValue = (masArg[index] != null) ? masArg[index].ToString() : "NULL";
                string argumentName = item.Name;

                if (argumentName.Equals("password"))
                    liItem.Arguments.Add(string.Format("{0}:{1}", argumentName, "********"));
                else
                    liItem.Arguments.Add(string.Format("{0}:{1}", argumentName, argumentValue));

                if (argumentName == "LiveID") liItem.LiveID = argumentValue;

                index++;
            }

            if (liItem.MethodName == ".ctor")
                liItem.MethodName = args.Method.ReflectedType.FullName;
            else
            {
                liItem.MethodName = args.Method.Name;

                //if (args.ReturnValue != null)
                //    liItem.ReturnValue = args.ReturnValue.ToString();
            }



            if (args.Exception != null)
            {
                liItem.ExceptionMessage = args.Exception.Message;
                liItem.ExceptionSource = args.Exception.StackTrace;
                liItem.IsSuccessed = false;
            }
            else
                liItem.IsSuccessed = true;

            liItem.LogEntryType = eletItem;

            liItem.WriteLogRecord();
        }
    }
}
